<?php
namespace App\Http\Model;

use App\Http\Services\EquipAuctionServices;
use App\Http\Services\EquipServices;
use Carbon\Carbon;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class EquipAuction extends Base
{
    protected $EquipAuctionTable = 'equip_auction';//拍卖记录表
    protected $equipUserTable = 'user_equip';//用户装备表
    protected $equipStream = 'equip_stream';//装备流水表
    protected $equipTypeTable = 'equip_type';//装备类型表
    protected $equipTable = 'equip';//装备表
    protected $equipShelveTable = 'equip_shelve';//装备商城货架
    protected $finance_jd_stream_table = 'finance_jd_stream';//金豆流水记录
    protected $fiance_wallet_table = 'finance_wallet';//用户钱包
    protected $room_table = 'room';//房间表
    protected $equipAuctionChatReoprt = 'equip_auction_chat_report';//举报公聊大厅用户

    protected $equipService;//装备服务
    protected $equipAuctionServices;//拍卖服务

    protected $unsaleEquipKey = 'UNSALE:EQUIP:USER:';//string 用户下架装备
    protected $userByEquipKey = 'USERBUYEQUIP:';//string 用户购买装备

    protected $errorLogName = 'error_auction_equip';//错误日志log
    protected $rate = 15;


    public function __construct(array $attributes = [])
    {
        parent::__construct($this->table, $attributes);
        $this->equipService = new EquipServices();
        $this->equipAuctionServices = new EquipAuctionServices();
    }

    //获取用户所持装备
    public function getUserEquip($user_id,$equip_type,$page,$limit){
        $where = function($q)use($equip_type,$user_id) {
            $q->where('user_id',$user_id);
            $q->where('user_equip.if_use','<',1);
            $q->where('num','>',0);
            //装备类型
            if(!empty($equip_type)){
                $q->where("equip_type",$equip_type);
            }
        };
        $res = DB::table($this->equipUserTable)
            ->leftJoin($this->equipTable,$this->equipTable.'.equip_id',$this->equipUserTable.'.equip_id')
            ->where($where)
            ->paginate($limit,['*'],'page',$page);
        $res = self::objToArray($res);
        $newData = [];
        if(!empty($res['data'])){
            foreach($res['data'] as $k=>$v){
                $newData[$k]['equip_id'] = $v['equip_id'];//装备id
                $newData[$k]['equip_name'] = $v['equip_name']; //装备名称
                $newData[$k]['equip_img'] = build_image($v['small_image']);//准备图片
                $newData[$k]['equip_big_img'] = build_image($v['image']);//装备大图
                $newData[$k]['equip_level'] = $v['equip_level'];//装备稀有度
                $newData[$k]['equip_jd_price'] = $v['jd_price'];//装备原始金豆价格

                $newData[$k]['nums'] = $v['num'];//所持数量
                $newData[$k]['equip_type'] = $v['equip_type'];//装备分类
                $newData[$k]['equip_sale_price_jd'] = $v['jd_sale_price_jd'];//装备出售推荐值
            }
        }
        //用户已装备的
        $usedWhere = function($qurey)use($equip_type,$user_id) {
                $qurey->where('user_id',$user_id);
                $qurey->where('if_use',1);
                if(!empty($equip_type)){
                    $qurey->where("equip_type",$equip_type);
                }
        };
        $usedEquip = DB::table($this->equipUserTable)
                    ->leftJoin($this->equipTable,$this->equipTable.'.equip_id',$this->equipUserTable.'.equip_id')
                    ->where($usedWhere)
                    ->get();
        $usedEquip = self::objToArray($usedEquip);
        $usedEquipArr = [];
        if(!empty($usedEquip)){
            foreach($usedEquip as $key=>&$val){
                $usedEquipArr[$key]['equip_id'] = $val['equip_id'];//装备id
                $usedEquipArr[$key]['equip_name'] = $val['equip_name']; //装备名称
                $usedEquipArr[$key]['equip_img'] = build_image($val['small_image']);//准备图片
                $usedEquipArr[$key]['equip_big_img'] = build_image($val['image']);//装备大图
                $usedEquipArr[$key]['equip_type'] = $val['equip_type'];//装备分类
            }
        }
        $res['used_equip'] = $usedEquipArr;
        $res['data'] = $newData;
        return $res;
    }

    //查询装备是否在装备中
    public function checkEquipStatus($equipId,$userid)
    {
        $res = DB::table($this->equipUserTable)->where(['user_id'=>$userid,'equip_id'=>$equipId])->first();
        $res = self::objToArray($res);
        return $res;
    }

    //减少用户所持数量
    public function decreaseData($equipId,$userid,$nums,$data_id){
        DB::table($this->equipUserTable)->where(['user_id'=>$userid,'equip_id'=>$equipId])->decrement('num',$nums);
        $datas['user_id'] = $userid;
        $datas['equip_id'] = $equipId;
        $datas['change_value'] = $nums;
        $datas['change_desc'] = '拍卖-扣除';
        $datas['equip_type'] = 51;//拍卖出售
        $datas['data_id'] = $data_id;
        $datas['data_type'] = 3;
        $status = DB::table($this->equipStream)->insert($datas);
        return $status;
    }

    //拍卖上架
    public function insertDatas($datas,$nums)
    {
        DB::beginTransaction();
        try{
            $insetid = DB::table($this->EquipAuctionTable)->insertGetId($datas);
            $status = $this->decreaseData($datas['equip_id'],$datas['user_id'],1,$insetid);
            DB::commit();
            return $status;
        }catch(\Exception $e){
            DB::rollBack();
            return false;
        }  
    }

    //拍卖下架
    public function unsaleEquip($user_id, $auctionId){
        try{
            //redis锁
            redis_lock($this->unsaleEquipKey.$user_id.':AUCTIONID:'.$auctionId,10);
            $update['sale_status'] = 3;//用户下架
            $update['unsale_time'] = date('Y-m-d H:i:s',time());
            $update = DB::table($this->EquipAuctionTable)->where(['auction_id'=>$auctionId,'user_id'=>$user_id])->update($update);

            if($update){
                //归还用户装备
                $auctionInfo = DB::table($this->EquipAuctionTable)->where('auction_id',$auctionId)->first();
                $auctionInfo = self::objToArray($auctionInfo);
                $param=[
                    [
                        'user_id'=>$user_id,
                        'equip_id'=>$auctionInfo['equip_id'],//装备id
                        'num'=>1,//归还数量
                        'equip_type' => 4,//拍卖下架
                        'data_id' => $auctionInfo['auction_id']//拍卖id
                    ]
                ];
                $result = $this->equipService->sendEquipToUser($param);
    
                if (!isset($result['code']) || $result['code'] !== 0) {
                    write_log($this->errorLogName, 'sendEquip ERROR 归还装备失败', ['param' => $param, 'result' => $result]);
                }
            }

            //redis解锁
            redis_unlock($this->unsaleEquipKey.$user_id.':AUCTIONID:'.$auctionId);

            return $update;

        }catch(\Exception $e){
            write_log($this->errorLogName,'ERROR 下架装备失败',['user_id'=>$user_id,'auction_id'=>$auctionId,'msg'=>$e->getMessage()]);
            return false;
        }  
    }

    /**获取拍卖列表
     * equip_type
        1	头部
        2	上衣
        3	披风
        4	武器
        5	下装
        6	鞋子
        7	装饰
        8	套装
        9	脸型
    **/
    public function getShopList($page, $limit, $kwd='', $equip_type=0, $equip_level=0, $user_id)
    {
        //获取拍卖上架的准备
        $where = function($q)use($kwd,$equip_level,$equip_type) {
                if (!empty($kwd)) {
                    $q->where("equip_name", "like",'%'.$kwd.'%');
                }
                //$q->where('sale_status',1);//上架中的数据
                //装备稀有度
                if(!empty($equip_level)){
                    $q->where("equip_level",$equip_level);
                }
                //装备类型
                if(!empty($equip_type)){
                    $q->where("equip_type",$equip_type);
                }
        };
        //先查询符合条件的装备表中的id
        $equipRes = DB::table($this->equipTable)->where($where)->get(['equip_id','equip_name','small_image','equip_level']);
        $equipRes = self::objToArray($equipRes);

        //整理符合条件的装备id
        $equipIds = array_column($equipRes,'equip_id');
        $equipInfos = array_column($equipRes,null,'equip_id');
        $datas = DB::table($this->EquipAuctionTable)
                ->where('sale_status',1)
                ->where('user_id','!=',$user_id)
                ->whereIn('equip_id',$equipIds)
                ->orderBy('sale_time','desc')
                ->paginate($limit,['*'],'page',$page);
        $datas = self::objToArray($datas);

        //重新整理数据
        if(!empty($datas['data']))
        {
            foreach($datas['data'] as $k=>$v){
                $newData[$k]['equip_name'] = $equipInfos[$v['equip_id']]['equip_name']; //装备名称
                $newData[$k]['equip_img'] = build_image($equipInfos[$v['equip_id']]['small_image']);//准备图片
                $newData[$k]['equip_level'] = $equipInfos[$v['equip_id']]['equip_level'];//装备稀有度
                $newData[$k]['equip_price'] = $v['price'];//装备出售金豆价格
                $newData[$k]['auction_id'] = $v['auction_id'];//拍卖行id
            }
            $datas['data'] = $newData;
        }
        
        return $datas;
    }

    //获取用户金豆
    public function getUserJd($userid){
        $userWalletInfo = DB::table($this->fiance_wallet_table)->where('user_id',$userid)->first();
        $userWalletInfo = self::objToArray($userWalletInfo);
        $userJdCount = !empty($userWalletInfo) ? $userWalletInfo['jd_balance'] : 0;
        return $userJdCount;
    }

    //获取装备类型
    public function getEquipType(){
        $data = DB::table($this->equipTypeTable)->get();
        $data = self::objToArray($data);
        return $data;
    }

    //随机取出8条装备信息用于系统上架
    public function roundEquip($equiptype){
        //查看APP端商城装备拍卖的商品,无法上架
        $appShopList = DB::table($this->equipShelveTable)->get();
        $appShopList = self::objToArray($appShopList);
        $appShopListIds = array_column($appShopList,'equip_id');

        $roundData = DB::connection($this->connection)
                    ->table($this->equipTable)
                    ->where('equip_type',$equiptype)
                    ->where('can_sale',1)
                    ->whereNotIn('equip_id',$appShopListIds)
                    ->inRandomOrder()
                    ->limit(8)
                    ->get();
        $roundData = self::objToArray($roundData);
        return $roundData;
    }

    //查询APP商店上架的装备信息
    public function appShopEquipInfo($equipId){
        $appShopInfo = DB::table($this->equipShelveTable)->where(['equip_id'=>$equipId])->first();
        $appShopInfo = self::objToArray($appShopInfo);
        return $appShopInfo;
    }

    //装备出售信息
    public function getEquipAuctionInfo($buy_id){
        $res = DB::table($this->EquipAuctionTable)->where(['auction_id'=>$buy_id,'sale_status'=>1])->first();
        $res = self::objToArray($res);
        return $res;
    }

    //给指定用户发装备+扣减金额
    public function userByEquip($user_id,$equipAuctionInfo){
            redis_lock($this->userByEquipKey.$user_id.':AUCTIONID:'.$equipAuctionInfo['auction_id'],10);
            $sysReturnJd = round($equipAuctionInfo['price'] * ($this->rate/100));//系统回收15%
            $roomReturnJd = round($equipAuctionInfo['price']* 0.09);//房间9%
            $finalPrice = round($equipAuctionInfo['price']-$sysReturnJd);//出售用户所得金豆
            //更新拍卖行表记录
            $updata['buy_user_id'] = $user_id;//购买用户id
            $updata['jd_complete_value'] = $finalPrice;//完成交易金豆数
            $updata['jd_commission_value'] = $sysReturnJd;//手续费
            
            $updata['buy_time'] = date('Y-m-d H:i:s',time());//购买时间
            $updata['sale_status'] = 2;//1=上架 2=已出售 3=用户下架 4=运营下架
            $updata['updeated_at'] = date('Y-m-d H:i:s',time());//更新时间

            DB::table($this->EquipAuctionTable)->where('auction_id',$equipAuctionInfo['auction_id'])->update($updata);

            //扣除用户金豆
            $config = config('pay');
            //金豆
            $jd_desc = $config['wallet_change_desc']['jd_equip_acution_decr'];
            //服务
            $result = $this->equipAuctionServices->useJdBuyEquip($user_id,$equipAuctionInfo['auction_id'],$equipAuctionInfo['num'],'-'.$equipAuctionInfo['price'],54,$jd_desc);
            if (!isset($result['code']) || $result['code'] !== 0) {
                write_log($this->errorLogName, 'costJdUser ERROR 扣减用户金豆失败', ['param' => $equipAuctionInfo, 'result' => $result]);
            }
            
            //出售用户加金豆
            $param=[
                'user_id'=>$equipAuctionInfo['user_id'],
                'info'=>['price'=>$finalPrice,'num'=>1,'auction_id'=>$equipAuctionInfo['auction_id'],'jd_type'=>6]
            ];

            $config = config('pay');
            //金豆描述
            $jd_desc = $config['wallet_change_desc']['jd_equip_acution_incr'];
            //服务
            $result = $this->equipAuctionServices->useJdBuyEquip($equipAuctionInfo['user_id'],$equipAuctionInfo['auction_id'],1,$finalPrice,6,$jd_desc);
            if (!isset($result['code']) || $result['code'] !== 0) {
                write_log($this->errorLogName, 'addJdUser ERROR 增加用户金豆失败', ['param' => $param, 'result' => $result]);
            }

            //若拍卖的装备在房间内上架的则给对应房间拥有者分9%金豆数
            if(!empty($equipAuctionInfo['room_id'])){
                //查询房间拥有者
                $roomInfo = DB::table($this->room_table)->where('room_id',$equipAuctionInfo['room_id'])->first();
                $roomInfo = self::objToArray($roomInfo);
                //必须是cbd
                if(!empty($roomInfo) && $roomInfo['business_type']==1){
                    //给房间所拥有者分金豆
                    $param=[
                        'user_id'=>$roomInfo['user_id'],
                        'info'=>['price'=>$roomReturnJd,'num'=>1,'auction_id'=>$equipAuctionInfo['auction_id'],'jd_type'=>7],
                    ];
                    //金豆描述
                    $jd_desc = $config['wallet_change_desc']['jd_equip_share_incr'];
                    //服务
                    $result = $this->equipAuctionServices->useJdBuyEquip($roomInfo['user_id'],$equipAuctionInfo['auction_id'],1,$roomReturnJd,7,$jd_desc);
                    if (!isset($result['code']) || $result['code'] !== 0) {
                        write_log($this->errorLogName, 'addJdUser ERROR 增加用户金豆失败', ['param' => $param, 'result' => $result]);
                    }
                    $updata['jd_union_value'] = $roomReturnJd;//公会分成
                    $updata['jd_system_value'] = intval($sysReturnJd - $roomReturnJd);
                    DB::table($this->EquipAuctionTable)->where('auction_id',$equipAuctionInfo['auction_id'])->update($updata);
                }   
            }else{
                //系统回收金豆15%记录
                $updata['jd_system_value'] = $sysReturnJd;//系统回收
                DB::table($this->EquipAuctionTable)->where('auction_id',$equipAuctionInfo['auction_id'])->update($updata);
            }

            //给用户发放装备
            $param=[
                [
                    'user_id'=>$user_id,
                    'equip_id'=>$equipAuctionInfo['equip_id'],//装备id
                    'num'=>1,//购买数量
                    'equip_type' => 3,//拍卖购买获得
                    'data_id' => $equipAuctionInfo['auction_id']//拍卖id
                ]
            ];
            $result = $this->equipService->sendEquipToUser($param);

            if (!isset($result['code']) || $result['code'] !== 0) {
                write_log($this->errorLogName, 'sendEquip ERROR 送装备失败', ['param' => $param, 'result' => $result]);
            }
            redis_unlock($this->userByEquipKey.$user_id.':AUCTIONID:'.$equipAuctionInfo['auction_id']);
            return true;
        
    
    }

    //获取用户拍卖记录
    public function auctionRecord($user_id, $type, $page=1, $limit=10, $roomId){
        $where = function($q)use($user_id,$roomId,$type) {  
            if($type==1 && empty($roomId)){
                $q->where('user_id',$user_id);
            }elseif($type == 2 && empty($roomId)){
                $q->where('buy_user_id',$user_id);
                $q->where('sale_status',2);
            }elseif(!empty($roomId)){
                $q->where('room_id',$roomId);
            }else{
                $q->where('user_id',$user_id);
            }
        };  
        //获取记录
        $res = DB::table($this->EquipAuctionTable)
        ->where($where)
        ->orderBy('sale_status','asc')
        ->paginate($limit,['*'],'page',$page);
        $res = self::objToArray($res);
        $newData = [];
        //重新整理数据
        if(!empty($res['data']))
        {
            $auctionIds = array_column($res['data'],'equip_id');
            //装备数据
            $equipInfos = DB::table($this->equipTable)->whereIn('equip_id',$auctionIds)->get(['equip_id','equip_name','small_image','equip_level']);
            $equipInfos = self::objToArray($equipInfos);
            $equipInfos = array_column($equipInfos,null,'equip_id');

            foreach($res['data'] as $k=>$v){
                $endTime = Carbon::today()->endOfDay()->toDateTimeString();
                $newData[$k]['equip_name'] = $equipInfos[$v['equip_id']]['equip_name']; //装备名称
                $newData[$k]['equip_img'] = build_image($equipInfos[$v['equip_id']]['small_image']);//准备图片
                $newData[$k]['equip_level'] = $equipInfos[$v['equip_id']]['equip_level'];//装备稀有度
                $newData[$k]['equip_price'] = $v['price'];//装备出售金豆价格
                $newData[$k]['auction_id'] = $v['auction_id'];//拍卖行id
                $newData[$k]['sale_status'] = $v['sale_status'];//1=出售中 2=已出售 3=用户下架 4=运营下架 5=系统回收
                if($v['sale_status'] == 1){
                    //拍卖时间加24小时
                    $endTime = Carbon::parse($v['sale_time'])->addHours(24);
                    $newData[$k]['time'] = strtotime($endTime);
                }elseif(in_array($v['sale_status'],['2','5'])){
                    $newData[$k]['time'] = $v['buy_time'];
                }elseif(in_array($v['sale_status'],['3','4'])){
                    $newData[$k]['time'] = $v['unsale_time'];
                } 
            }
            $res['data'] = $newData;
        }
        return $res;
    }

    //获取装备信息
    public function EquipInfo($equipId){
        $info = DB::table($this->equipTable)->where('equip_id',$equipId)->first();
        $info = self::objToArray($info);
        return $info;
    }

    /**
     * 倒计时显示
     * @param $beginDate  开始日期
     * @param $endDate    结束日期
     * @return string
     */
    function timeCalculation($beginDate, $endDate)
    {
        $subTime = strtotime($endDate) - strtotime($beginDate);
        $day = $subTime > 86400 ? floor($subTime / 86400) : 0;
        $subTime -= $day * 86400;
        $hour = $subTime > 3600 ? floor($subTime / 3600) : 0;
        $subTime -= $hour * 3600;
        $minute = $subTime > 60 ? floor($subTime / 60) : 0;
        $subTime -= $minute * 60;
        $second = $subTime;
    
        $dayText = $day ? $day . '天' : '';
        $hourText = $hour ? $hour . '小时' : '';
        $minuteText = $minute ? $minute . '分' : '';
        $date = $dayText . $hourText . $minuteText . $second . '秒';
        return $date;
    }

    //获取费率
    public function getRate(){
        $data = [
            'rate' => $this->rate,
            'unsale_time'=> 24,
        ];
        return $data;
    }

    //举报用户公聊大厅
    public function insertReport($param){
        $status = DB::table($this->equipAuctionChatReoprt)->insert($param);
        return $status;
    }
}